package org.metasketch.simulator.tools.channels.dynamic;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import org.metasketch.demo.model.ActorRole;
import org.metasketch.demo.model.DEMOModel;
import org.metasketch.demo.model.TransactionKind;
import org.metasketch.simulator.petri.PetriNet;
import org.metasketch.simulator.petri.PetriNetSet;
import org.metasketch.simulator.petri.Transition;
import org.metasketch.simulator.resources.Resource;
import org.metasketch.simulator.resources.ResourceBank;
import org.metasketch.simulator.resources.ResourceBase;
import org.metasketch.simulator.resources.ResourceClass;
import org.metasketch.simulator.resources.ResourceRequirements;
import org.metasketch.simulator.tools.Registry;
import org.metasketch.simulator.tools.channels.ChannelDefinition;
import org.metasketch.simulator.tools.generic.Expression;
import org.metasketch.simulator.tools.generic.GenericInfo;
import org.metasketch.simulator.tools.generic.ResourceProduction;
import org.metasketch.simulator.tools.generic.ResourceRequirement;
import org.metasketch.simulator.tools.generic.Variable;
import org.metasketch.simulator.tools.transactions.StepDefinition;
import org.metasketch.simulator.tools.transactions.StepDefinitionValidator;
import org.metasketch.simulator.tools.transactions.StepName;
import org.metasketch.simulator.transformation.PetriNetSimulationPackage;

import com.thoughtworks.xstream.XStream;

public class MainDynamicTransactionChannelLoader {

	protected static XStream getXStream() {
		XStream xstream = new XStream();
		xstream.autodetectAnnotations(true);

		xstream.processAnnotations(ChannelDistribution.class);
		xstream.processAnnotations(StepChannel.class);
		xstream.processAnnotations(Transaction.class);

		xstream.processAnnotations(MainDynamicTransactionChannels.class);

		return xstream;
	}

	protected static MainDynamicTransactionChannels load(File file)
			throws Throwable {

		XStream xstream = getXStream();

		FileReader reader = new FileReader(file);
		MainDynamicTransactionChannels cfg = (MainDynamicTransactionChannels) xstream
				.fromXML(reader);
		reader.close();

		return cfg;

	}

	public static MainDynamicTransactionChannels getResources(DEMOModel model,
			PetriNetSimulationPackage simulationPackage, File file)
			throws Throwable {
		MainDynamicTransactionChannels cfg = load(file);

		ResourceBank bank = simulationPackage.getResources();
		PetriNetSet petriNetSet = simulationPackage.getPetriNets();
		Registry reg = simulationPackage.getRegistry();

		List<Transaction> transactions = cfg.getTransactions();

		for (Transaction transaction : transactions) {
			List<StepChannel> steps = transaction.getSteps();
			for (StepChannel step : steps) {
				StepDefinitionValidator.setStepNames(step);

				List<ChannelDistribution> channels = step.getChannels();
				for (ChannelDistribution channel : channels) {

					channel.setChannels(new ArrayList<ChannelDefinition>());

					String aliases = channel.getAliases();

					StringTokenizer st = new StringTokenizer(aliases);
					while (st.hasMoreTokens()) {
						String token = st.nextToken();

						ChannelDefinition originalChannel = (ChannelDefinition) reg
								.get(token);
						if (originalChannel == null)
							throw new Exception(
									"Can't find the channel with alias: "
											+ token);

						channel.getChannels().add(originalChannel);

					}

				}
			}

		}

		return cfg;

	}

}
